/**
 * Copyright © 2021-2025 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.wutu.nbyjk8.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.google.common.collect.Lists;
import com.wutu.nbyjk8.domain.DataSourceManage;
import com.wutu.nbyjk8.listener.ExcelListener;
import com.wutu.nbyjk8.mapper.DataSourceManageMapper;
import com.wutu.nbyjk8.service.impl.DataSourceManageService;
import com.wutu.nbyjk8.utils.FileUploadUtils;
import com.wutu.nbyjk8.vo.FiledsVO;
import com.wutu.nbyjk8.vo.QueryVO;
import com.wutu.nbyjk8.vo.ResVO;
import com.wutu.nbyjk8.vo.SaveVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.poifs.filesystem.FileMagic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;

/**
 * 数据源管理Controller
 *
 * @author 朱欢乐
 * @version 2023-06-19
 */

@Api(tags = "数据源管理")
@RestController
@RequestMapping(value = "/datasourcemanage/dataSourceManage")
@Slf4j
@JsonIgnoreProperties(ignoreUnknown = true)
public class DataSourceManageController extends BaseController {

    @Autowired
    private DataSourceManageService dataSourceManageService;

    @Autowired
    DataSourceManageMapper dataSourceManageMapper;

    @Value("${baseFileUrl}")
    String baseFileUrl;

    @Autowired
    RestTemplate restTemplate;

    private Map<String, Object> map = new HashMap<>();


    /**
     * 数据源管理列表数据
     */
    @ApiOperation(value = "查询数据源管理列表数据")
    @GetMapping("list")
    public ResponseEntity<IPage<DataSourceManage>> list(@RequestParam(value = "name", required = false) String name
            , @RequestParam(value = "eName", required = false) String eName, Page<DataSourceManage> page) throws Exception {
        QueryWrapper<DataSourceManage> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(eName)) {
            queryWrapper.like("e_name", eName);
        }
        if (StringUtils.isNotBlank(name)) {
            queryWrapper.like("name", name);
        }
        IPage<DataSourceManage> result = dataSourceManageService.page(page, queryWrapper);
        return ResponseEntity.ok(result);
    }


    /**
     * 根据Id获取数据源管理数据
     */
    @ApiOperation(value = "根据Id获取数据源管理数据")
    @GetMapping("queryById")
    public ResponseEntity<DataSourceManage> queryById(String id) {
        return ResponseEntity.ok(dataSourceManageService.getById(id));
    }

    /**
     * 保存数据源管理
     */
    @ApiOperation(value = "保存数据源管理")
    @PostMapping("save")
    public ResponseEntity<String> save(@RequestBody DataSourceManage dataSourceManage) {
        //新增或编辑表单保存
        dataSourceManageService.saveOrUpdate(dataSourceManage);
        // 解析数据创建表
        // 删除表
        String eName = dataSourceManage.getEName();
        List<FiledsVO> filedsVOS = JSONObject.parseArray(dataSourceManage.getFileds(), FiledsVO.class);
        dataSourceManageMapper.deletetable(eName);
        // 新建表
        StringBuilder sql = new StringBuilder("CREATE TABLE \"fuse\"");
        sql.append(".");
        sql.append("\"");
        sql.append(eName);
        sql.append("\" (");
        sql.append("\"id\"");
        sql.append(" varchar(5000) DEFAULT NULL ");
        //"添加字段"
        boolean flagPoi = false;
        for (int i = 0; i < filedsVOS.size(); i++) {

            sql.append(",");
            FiledsVO filedsVO = filedsVOS.get(i);
            sql.append("\"");
            sql.append(filedsVO.getName());
            sql.append("\"");
            if ("lat".equals(filedsVO.getName()) || "lon".equals(filedsVO.getName())) {
                sql.append(" float8 ");
                flagPoi = true;
            } else {
                sql.append(" varchar(5000) DEFAULT NULL ");
            }

        }
        // 包含lon或者得lat得设置poi
        if (flagPoi) {
            sql.append(",");
            sql.append("\"poi\"");
            sql.append(" bytea");
        }
        sql.append(") ;");
        dataSourceManageMapper.createable(sql.toString());
        return ResponseEntity.ok("保存数据源管理成功");
    }


    /**
     * 保存数据源管理
     */
    @ApiOperation(value = "保存数据源管理 其他属性")
    @PostMapping("saveOthers")
    public ResponseEntity<String> saveOthers(@RequestBody DataSourceManage dataSourceManage) {
        //新增或编辑表单保存
        dataSourceManageService.saveOrUpdate(dataSourceManage);
        // 解析数据创建表
        return ResponseEntity.ok("保存数据源管理成功");
    }


    /**
     * 删除数据源管理
     */
    @ApiOperation(value = "删除数据源管理")
    @DeleteMapping("delete")
    public ResponseEntity<String> delete(String ids) {
        String idArray[] = ids.split(",");
        dataSourceManageService.removeByIds(Lists.newArrayList(idArray));
        return ResponseEntity.ok("删除数据源管理成功");
    }


    @ApiOperation(value = "保存数据源管理")
    @PostMapping("selectByType")
    public ResponseEntity<ResVO> selectByType(@RequestBody QueryVO queryVO) {
        return ResponseEntity.ok(dataSourceManageService.selectByType(queryVO));
    }

    @ApiOperation(value = "导出模板")
    @GetMapping("exportExcel")
    public void exportExcel(@RequestParam(value = "id") String id, HttpServletResponse response) throws IOException {
        DataSourceManage dataSourceManage = dataSourceManageService.getById(id);
        List<FiledsVO> filedsVOS = JSONObject.parseArray(dataSourceManage.getFileds(), FiledsVO.class);
        List<List<String>> lists = new ArrayList<>();
        List<String> listdata = new ArrayList<>();
        for (FiledsVO filedsVO : filedsVOS) {
            List<String> list = new ArrayList<>();
            //list.add(filedsVO.getName());
            list.add(filedsVO.getRemake());
            lists.add(list);
        }
        response.reset();
        //设置Mime-Type
        response.setContentType("application/msword");
        response.setHeader("Access-Control-Allow-Origin", "*");//允许所有请求跨域
        response.setHeader("Access-Control-Allow-Methods", "*");//允许跨域的请求方法GET, POST, HEAD 等
        response.setHeader("Access-Control-Allow-Headers", "*");//允许跨域的请求头
        response.setHeader("Access-Control-Allow-Credentials", "true");//是否携带cookie
//设置下载默认文件名
        String fileName = URLEncoder.encode(dataSourceManage.getName() + "导入模板", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls");
        EasyExcel.write(response.getOutputStream())
                .head(lists)
                .excelType(ExcelTypeEnum.XLS)
                .sheet("sheet1").doWrite(listdata);
    }
    @ApiOperation(value = "插入数据")
    @PostMapping("saveData")
    public ResponseEntity<Object> updateOrSave(@RequestBody SaveVO saveVO) {
        dataSourceManageService.updateOrSave(saveVO);
        return ResponseEntity.ok("保存成功");
    }

    @ApiOperation(value = "删除数据")
    @PostMapping("deleteData")
    public ResponseEntity<Object> deleteByTable(@RequestBody SaveVO saveVO) {
        dataSourceManageService.delete(saveVO);
        return ResponseEntity.ok("删除成功");
    }


    @ApiOperation(value = "列表查询")
    @PostMapping("selectList")
    public ResponseEntity<Object> selectList(@RequestBody QueryVO queryVO) {
        return ResponseEntity.ok(dataSourceManageService.selectList(queryVO));
    }

    @ApiOperation(value = "设置point")
    @PostMapping("setPoint")
    public ResponseEntity<Object> setPoint(@RequestBody QueryVO queryVO) {
        return ResponseEntity.ok(dataSourceManageService.setPoint(queryVO));
    }


    /**
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/uploadFile")
    @Transactional
    public ResponseEntity<Object> uploadFile(MultipartFile file) throws IOException {
        String check = FileUploadUtils.check(file, 50, FileMagic.OLE2, FileMagic.OOXML);
        if (!FileUploadUtils.SUCCSEE.equals(check)) {
            return ResponseEntity.badRequest().body(check);
        }

        String path = UUID.randomUUID().toString();
        String fileName = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf("."));
        String fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        path = "/" + path + fileName;
        // 在文件夹下创建对象
        this.uploadFile1(file, baseFileUrl + path + fileType);
        return ResponseEntity.ok(path + fileType);
    }

    /**
     * @param response
     * @throws IOException
     */
    @GetMapping("/downloadFile")
    public void downloadFile(String filePath, HttpServletResponse response) {
        this.download1(filePath, response);
    }


    private void uploadFile1(MultipartFile file, String path) {
        try (FileOutputStream fs = new FileOutputStream(path); InputStream inputStream = file.getInputStream()) {
            byte[] buffer = new byte[1024 * 10];
            int byteread = 0;
            while ((byteread = inputStream.read(buffer)) != -1) {
                fs.write(buffer, 0, byteread);
                fs.flush();
            }
        } catch (Exception e) {
            log.info("保存文件失败{}", e);
        }
    }

    private HttpServletResponse download1(String path, HttpServletResponse response) {
        try (InputStream fis = new FileInputStream(baseFileUrl + path); OutputStream toClient = new BufferedOutputStream(response.getOutputStream());) {
            // path是指欲下载的文件的路径。
            File file = new File(path);
            // 取得文件名。
            String filename = file.getName();
            // 取得文件的后缀名。
            //String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
            // 以流的形式下载文件。
            byte[] buffer = new byte[1024 * 1024];
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
            response.addHeader("Content-type", "application/octet-stream");
            response.setContentType("application/octet-stream");
            response.addHeader("Access-Control-Allow-Origin", "*");
            int byteread;
            int sum = 0;
            while ((byteread = fis.read(buffer)) != -1) {
                sum += byteread;
                toClient.write(buffer, 0, byteread);
            }
            response.addHeader("Content-Length", "" + sum);
            toClient.flush();
        } catch (IOException ex) {
            log.error("下载文件失败{}", ex);

        }
        return response;
    }

    /**
     * 查询单兵接口
     *
     * @param jsonObject1
     */
    @PostMapping("/db")
    public List<Object> db(@RequestBody JSONObject jsonObject1) {
        List<Object> list = new ArrayList<>();
        String device_ids = jsonObject1.getString("device_ids");
        String[] split = device_ids.split(",");
        if (split.length < 2 && StringUtils.isBlank(split[0])) {
            return new ArrayList<>();
        }
        for (String s : split) {
            HttpHeaders requestHeaders = new HttpHeaders();
            String Host = jsonObject1.getString("X-Host");
            String XNonce = jsonObject1.getString("X-Nonce");
            String signature = jsonObject1.getString("X-Signature");
            String token = jsonObject1.getString("X-Token");
            String visitor = jsonObject1.getString("X-Visitor");
            //requestHeaders.set("Accept", "application/json, text/plain, */* ");
            //requestHeaders.set("Accept-Encoding", "gzip, deflate");
            //requestHeaders.set("Accept-Language", "zh-CN,zh;q=0.9");
            //requestHeaders.set("Connection", "keep-alive");
            requestHeaders.set("Host", Host);
            requestHeaders.set("Origin", "http://localhost:8080");
            requestHeaders.set("Referer", "http://localhost:8080");
            requestHeaders.set("X-Host", Host);
            requestHeaders.set("X-Nonce", XNonce);
            requestHeaders.set("X-Signature", signature);
            requestHeaders.set("X-Timestamp", XNonce);
            requestHeaders.set("X-Token", token);
            requestHeaders.set("X-Visitor", visitor);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("device_ids", s);
            HttpEntity requestEntity = new HttpEntity(jsonObject, requestHeaders);
            String url = "http://10.19.212.132:8089/nuas/api/v1/locations?device_ids=" + s;
            HttpEntity<String> response = restTemplate.exchange(
                    url,
                    HttpMethod.GET,
                    requestEntity,
                    String.class
            );
            JSONObject body = JSONObject.parseObject(response.getBody().toString());
            JSONArray data = body.getJSONArray("data");
            if (data.size() > 0) {
                list.add(data.get(0));
                map.put(s, data.get(0));
            } else {
                Object list1 = map.get(s);
                if (list1 != null) {
                    list.add(list1);
                }
            }
        }
        return list;
    }
}
